load("//bazel:tachyon.bzl", "if_aarch64", "if_has_avx512", "if_x86_64")
load(
    "//bazel:tachyon_cc.bzl",
    "tachyon_avx512_defines",
    "tachyon_cc_benchmark",
    "tachyon_cc_library",
    "tachyon_cc_unittest",
)

package(default_visibility = ["//visibility:public"])

tachyon_cc_library(
    name = "arithmetics",
    hdrs = ["arithmetics.h"],
    deps = [
        ":arithmetics_results",
        "//tachyon/base:bit_cast",
        "//tachyon/base:compiler_specific",
        "//tachyon/build:build_config",
        "@com_google_absl//absl/numeric:int128",
    ],
)

tachyon_cc_library(
    name = "arithmetics_results",
    hdrs = ["arithmetics_results.h"],
    deps = ["@com_google_absl//absl/strings"],
)

tachyon_cc_library(
    name = "big_int",
    srcs = ["big_int.cc"],
    hdrs = ["big_int.h"],
    deps = [
        ":arithmetics",
        ":bit_traits_forward",
        "//tachyon/base:bit_cast",
        "//tachyon/base:endian_utils",
        "//tachyon/base:random",
        "//tachyon/base/buffer:copyable",
        "//tachyon/base/json",
        "//tachyon/base/strings:string_util",
        "//tachyon/build:build_config",
        "//tachyon/math/base/gmp:gmp_util",
    ],
)

tachyon_cc_library(
    name = "bit_iterator",
    hdrs = ["bit_iterator.h"],
    deps = [":bit_traits_forward"],
)

tachyon_cc_library(
    name = "bit_traits_forward",
    hdrs = ["bit_traits_forward.h"],
)

tachyon_cc_library(
    name = "byinverter",
    hdrs = ["byinverter.h"],
    deps = [
        "//tachyon/base:bits",
        "//tachyon/math/base:big_int",
        "@com_google_absl//absl/numeric:int128",
    ],
)

tachyon_cc_library(
    name = "const_init",
    hdrs = ["const_init.h"],
)

tachyon_cc_library(
    name = "egcd",
    hdrs = ["egcd.h"],
)

tachyon_cc_library(
    name = "field",
    hdrs = ["field.h"],
    deps = [":ring"],
)

tachyon_cc_library(
    name = "groups",
    hdrs = ["groups.h"],
    deps = [
        ":semigroups",
        "//tachyon/base:parallelize",
        "//tachyon/base/containers:container_util",
        "//tachyon/base/types:always_false",
    ],
)

tachyon_cc_library(
    name = "parallelize_threshold",
    hdrs = ["parallelize_threshold.h"],
)

tachyon_cc_library(
    name = "rational_field",
    hdrs = ["rational_field.h"],
    deps = [
        ":field",
        "//tachyon/base:optional",
        "//tachyon/base:template_util",
    ],
)

tachyon_cc_library(
    name = "ring",
    hdrs = ["ring.h"],
    deps = [
        ":groups",
        "//tachyon/base:parallelize",
    ],
)

tachyon_cc_library(
    name = "semigroups",
    hdrs = ["semigroups.h"],
    deps = [
        ":big_int",
        ":bit_iterator",
        "//tachyon/base:bits",
        "//tachyon/base:logging",
        "//tachyon/base:parallelize",
        "//tachyon/base/containers:container_util",
        "//tachyon/base/types:always_false",
        "@com_google_absl//absl/types:span",
    ],
)

tachyon_cc_library(
    name = "sign",
    srcs = ["sign.cc"],
    hdrs = ["sign.h"],
    deps = [
        "//tachyon/base:logging",
        "//tachyon/base/strings:string_util",
    ],
)

tachyon_cc_library(
    name = "simd_int",
    srcs = if_x86_64([
        "simd_int128_x86.cc",
        "simd_int256_x86.cc",
    ]) + if_has_avx512([
        "simd_int512_x86.cc",
    ]) + if_aarch64([
        "simd_int128_arm64.cc",
    ]),
    hdrs = ["simd_int.h"],
    copts = if_x86_64([
        "-mavx2",
    ]) + if_has_avx512([
        "-mavx512f",
    ]),
    defines = tachyon_avx512_defines(),
    deps = [
        "//tachyon:export",
        "//tachyon/base:bit_cast",
        "//tachyon/base:compiler_specific",
        "//tachyon/base:logging",
        "//tachyon/build:build_config",
        "//tachyon/math/base:big_int",
    ],
)

tachyon_cc_unittest(
    name = "base_unittests",
    srcs = [
        "arithmetics_unittest.cc",
        "big_int_unittest.cc",
        "bit_iterator_unittest.cc",
        "byinverter_unittest.cc",
        "egcd_unittest.cc",
        "field_unittest.cc",
        "groups_unittest.cc",
        "rational_field_unittest.cc",
        "semigroups_unittest.cc",
        "sign_unittest.cc",
        "simd_int_unittest.cc",
    ],
    deps = [
        ":big_int",
        ":bit_iterator",
        ":byinverter",
        ":egcd",
        ":groups",
        ":rational_field",
        ":sign",
        ":simd_int",
        "//tachyon/base:optional",
        "//tachyon/base/buffer:vector_buffer",
        "//tachyon/base/containers:container_util",
        "//tachyon/base/strings:string_number_conversions",
        "//tachyon/math/elliptic_curves/msm/test:variable_base_msm_test_set",
        "//tachyon/math/elliptic_curves/short_weierstrass/test:sw_curve_config",
        "//tachyon/math/finite_fields/test:finite_field_test",
        "//tachyon/math/finite_fields/test:gf7",
        "@com_google_absl//absl/container:inlined_vector",
        "@com_google_absl//absl/types:span",
    ],
)

tachyon_cc_benchmark(
    name = "batch_inverse_benchmark",
    srcs = ["batch_inverse_benchmark.cc"],
    deps = [
        "//tachyon/base/containers:container_util",
        "//tachyon/math/elliptic_curves/bn/bn254:fq",
    ],
)
